#ifndef __MY_MV_BITMAP
#define __MY_MV_BITMAP

enum BMRatioTypes {
  bmrFree,
  bmrFit,
  bmrWidth,
  bmrHeight
};

LOCALSTRUCT( MVPluginFile )
};

#define CM_RGB                  GFL_CM_RGB     //0 Red-Green-Blue
#define CM_GREY                 GFL_CM_GREY    //1 Greyscale
#define CM_CMY                  GFL_CM_CMY     //2 Cyan-Magenta-Yellow
#define CM_CMYK                 GFL_CM_CMYK    //3 Cyan-Magenta-Yellow-Black
#define CM_YCBCR                GFL_CM_YCBCR   //4 YCbCr
#define CM_YUV16                GFL_CM_YUV16   //5 YUV 16bits
#define CM_LAB                  GFL_CM_LAB     //6 Lab
#define CM_LOGLUV               GFL_CM_LOGLUV  //7 Log Luv
#define CM_LOGL                 GFL_CM_LOGL    //8 Log L

#define CMP_NO_COMPRESSION      GFL_NO_COMPRESSION        //0 No compression
#define CMP_RLE                 GFL_RLE                   //1 Packbits
#define CMP_LZW                 GFL_LZW                   //2 LZW
#define CMP_JPEG                GFL_JPEG                  //3 JPEG
#define CMP_ZIP                 GFL_ZIP                   //4 ZIP
#define CMP_SGI_RLE             GFL_SGI_RLE               //5 GSI Packbits
#define CMP_CCITT_RLE           GFL_CCITT_RLE             //6 CCITT RLE
#define CMP_CCITT_FAX3          GFL_CCITT_FAX3            //7 Fax Group 3
#define CMP_CCITT_FAX3_2D       GFL_CCITT_FAX3_2D         //8 Fax Group 3-2D
#define CMP_CCITT_FAX4          GFL_CCITT_FAX4            //9 Fax Group 4
#define CMP_WAVELET             GFL_WAVELET               //10 Wavelette
#define CMP_UNKNOWN_COMPRESSION GFL_UNKNOWN_COMPRESSION   //255 Other compression

LOCALSTRUCT( MVBitmapInfo )
  int        Width;
  int        Height;
  char       FormatName[13];
  char       Description[100];
  WORD       Xdpi;
  WORD       Ydpi;
  WORD       BitsPerPlane;
  WORD       NumberOfPlanes;
  DWORD      BytesPerPlane;
  int        NumberOfImages;
  DWORD      FileSize;
  DWORD      ColorModel;                  //CM_xxx
  DWORD      Compression;                 //CMP_xxx
  char       CompressionDescription[100];
};

LOCALSTRUCTBASE( MVBitmap_t, public BITMAPINFO )
  RGBQUAD    rgb[ 256 ];
  LPVOID     Bits;
};

LOCALSTRUCTBASE( MVBitmapPluginFile, public MVPluginFile )
  public:
    virtual bool         GetBitmapInfo( PMVBitmapInfo bi )               = 0;
    virtual bool         CreateBitmap( PMVBitmap_t bmI )                 = 0;
    virtual void         GetDimensions( LPSIZE sz )                      = 0;
    virtual CONSTSTR     LastError( void )                               = 0;
};

LOCALSTRUCTBASE( GFLBitmap, public MVBitmapPluginFile )
    GFL_BITMAP            *Handle;
    GFL_FILE_INFORMATION   fi;
    GFL_ERROR              err;

  private:
    void Destroy( void );

  public:
    GFLBitmap( void );
    ~GFLBitmap() { Shutdown(); }

    bool Load( CONSTSTR FileName );
    int  Width( void )                { return Handle->Width; }
    int  Height( void )               { return Handle->Height; }

    virtual bool      GetBitmapInfo( PMVBitmapInfo bi );
    virtual bool      CreateBitmap( PMVBitmap_t bmI );
    virtual CONSTSTR  LastError( void )                      { return GflGetErrorString(err); }
    virtual void      GetDimensions( LPSIZE sz )             { sz->cx = Handle->Width; sz->cy = Handle->Height; }
    virtual void      Shutdown( void )                       { Destroy(); }
};

//------------------------------------------------------------------------
LOCALSTRUCTBASE( MVProxy, public MVPluginFile )
    PMVPluginFile File;

  public:
    MVProxy( PMVPluginFile f ) { File = f; }
    virtual ~MVProxy() {}

    virtual void         Initialize( void )               {}
    virtual void         SetOutputArea( const MyRect& r ) {}
    virtual void         CloseOutput( void )              {}
    virtual void         Paint( HDC dc, const MyRect& r, MyRect& dr ) {}
};

LOCALSTRUCTBASE( MVBitmapProxy, public MVProxy )
    int               Width, Height;
    MVBitmapInfo      mvI;
    HDC               paintDC,
                      screenDC;
    HBITMAP           paintBitmap,
                      oldBitmap,
                      screenBitmap;

  private:
    void SetMaxOffsets( void );
    void PaintBmp( HDC dc,int x, int y, int w, int h );
    void AreaChanged( void );

    void CreatePaintDC( void );      //Ceate DC

    void CreatePaintBitmap( void );  //Create HBITMAP
    void ClosePaintBitmap( void );   //Delete HBITMAP
    void FillPaintBitmap( void );    //Draw pixels on HBITMAP

  public:
    MVBitmapProxy( PMVPluginFile f );
    ~MVBitmapProxy();

    virtual void  Initialize( void );
    virtual void  SetOutputArea( const MyRect& r );
    virtual void  CloseOutput( void );
    virtual void  Paint( HDC dc, const MyRect& r, MyRect& dr );

    void          BitmapChanged( void );  //Create pixels and HBITMAP
    void          BitmapClose( void );    //Deletes pixels and HBITMAP
    LPVOID        Bits( void )            { return bmI.Bits; }

    void          SetRatio( BMRatioTypes type,int v );
    void          ZoomFit( void )          { SetRatio( bmrFit, 0 ); }
    void          ZoomHeight( void )       { SetRatio( bmrHeight, 0 ); }
    void          ZoomWidth( void )        { SetRatio( bmrWidth, 0 ); }
    void          SetOffsets( int x,int y );

    int           Raster2Screen( int v ) { return MulDiv( Ratio, v, 100 ); }
    int           Screen2Raster( int v ) { return MulDiv( v, 100, Ratio ); }

    MVBitmap_t bmI;
    int        OffX, OffY;
    int        MaxX, MaxY;
    int        Ratio;
};
#endif